package com.sky.module.suppot.file.service.impl;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.sky.common.exception.SkySecurityException;
import com.sky.module.suppot.file.domain.entity.FileEntity;
import com.sky.module.suppot.file.domain.vo.FileEntityVo;
import com.sky.module.suppot.file.s3.OssProperties;
import com.sky.module.suppot.file.service.FileStorageService;
import com.sky.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FilenameUtils;
import org.omg.PortableInterceptor.SYSTEM_EXCEPTION;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.time.LocalDateTime;
import java.util.UUID;

/**
 * @author
 * @date 2023/2/28 23:12
 **/
@Slf4j
public class FileStorageServiceLocalImpl implements FileStorageService {

    @Value("${oss.path}")
    private String localPath;

    @Autowired
    private OssProperties ossProperties;


    @Override
    public Result<FileEntity> fileUpload(MultipartFile multipartFile, String folder) {
        Long beginTime = System.currentTimeMillis();
        final String originalFilename = multipartFile.getOriginalFilename();
        File fileTemp = null;
        if (multipartFile == null) {
            throw new SkySecurityException("文件不能为空", 500);
        }
        // 如果给的目录不是斜杠结尾 就加一个结尾
        if (!folder.endsWith("/")) {
            folder = folder + "/";
        }

        // 加上  /home/smart_admin_v2/upload/avatar/
        String filePath = localPath + folder;
        final File diretory = new File(filePath);
        if (!diretory.exists()) { // filepath 文件目录不存在的话，就创建这个目录
//         如果目录不存在就进行创建
            diretory.mkdirs();
        }


        // 新文件名  87591a89e4234fd895108f5ed6661b08_20230302095931.jpg 防止文件重复
        String newFileName = this.generateFileName(originalFilename);
        //     本地上传只需要这2个 一个模块名和文件名
        String fileKey = folder + newFileName;
        log.info(fileKey + "文件开始上传");

        // 创建一个临时文件  filepath + filekey 就是目录加上文件名字 创建文件
//         /home/smart_admin_v2/upload/avatar/87591a89e4234fd895108f5ed6661b08_20230302095931.jpg

        fileTemp = new File(new File(filePath + newFileName).getAbsolutePath());
        Long endTime = System.currentTimeMillis();
        log.info(fileKey + "文件上传完成");
        long consumptionTime = endTime - beginTime;
        log.info("消耗时间为" + (endTime - beginTime) + "毫秒");
        log.info("上传文件成功 fileName :" + multipartFile.getOriginalFilename());
        FileEntityVo fileEntityVo = null;
        FileEntity fileEntity = null;
//          数据库不需要保存文件路径 只需要保存public key 文件路径即可，因为域名有可能不同，使用的不同的oss
        try {
            String fileType = FilenameUtils.getExtension(originalFilename);

            String url = ossProperties.getEndpoint() + fileKey;
            multipartFile.transferTo(fileTemp);
//            TODO 获取上传的名字，这里出现了类型转换异常
//            User user = (User) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
//            String username = user.getUsername();
            // 获取文件系统存储名字 比如 minio
            String storageType = ossProperties.getStorageType();

            fileEntity = FileEntity.builder()
                    // 文件大小

                    .fileSize(fileTemp.length())
                    .fileType(fileType)
                    .storageType(storageType) // 存储文件系统名字
                    .createTime(LocalDateTime.now())
                    .fileKey(fileKey)
                    .fileName(originalFilename)
                    .consumptionTime(consumptionTime)
                    .creatorName("")
                    .folderType(1).build();
        } catch (Exception e) {
            // 如果保存失败 就删除之前已经创建好的临时文件
            if (fileTemp.exists() && fileTemp.isFile()) {
                fileTemp.delete();
            }
            log.error("文件上传失败");

        }


//        return  Res
        return Result.ok(fileEntity).message("success");
//        TODO 基于本地的存储

    }

    @Override
    public Result<?> delete(String fileKey) {
        return null;
    }


    @Override
    public Result<String> getFileUrl(String fileKey) {
//        final String substring = fileKey.substring(fileKey.lastIndexOf("/")
//        );
        String url = ossProperties.getUrl() + "/" + fileKey;
//        return rest
        return Result.ok(url);
    }


    /**
     * 生成文件名字
     * 当前年月日时分秒 +32位 uuid + 文件格式后缀
     *
     * @param originalFileName
     * @return String
     */
    private String generateFileName(String originalFileName) {
        return generateFileNameByType(FilenameUtils.getExtension(originalFileName));
    }

    /**
     * 根据文件类型 生成文件名，格式如下：
     * [uuid]_[日期时间]_[文件类型]
     *
     * @param fileType
     * @return
     */
    private String generateFileNameByType(String fileType) {
        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
        String time = LocalDateTimeUtil.format(LocalDateTime.now(), DatePattern.PURE_DATETIME_FORMATTER);
        return uuid + "_" + time + "." + fileType;
    }

}
